#include "StdAfx.h"
#include ".\hashtable.h"

unsigned int CHashTable::hash(const char *str)
{ 
	register unsigned int h; 
	register unsigned char *p; 


	for(h=0, p = (unsigned char *)str; *p ; p++) 
		h = 31 * h + *p; 


	return h%m_nTableSize;
}


CHashTable::CHashTable(int size)
{
	if (size > 0)
		m_pHashTable = new HashElement[size];
	m_nTableSize = size;
}

void CHashTable::deleteItem(HashElement* pElement)
{
	delete[] pElement->_key;
	//delete[] pElement->_value;
	if (pElement->_prvi) pElement->_prvi->_next = pElement->_next;
	if (pElement->_next) pElement->_next->_prvi = pElement->_prvi;
	delete pElement;
}
CHashTable::~CHashTable(void)
{
	clear();
	delete[] m_pHashTable;
}

void CHashTable::clear()
{
	HashElement* pElement;
	for (int i = 0;i< m_nTableSize ; ++i)
	{
		pElement = &m_pHashTable[i];
		while(pElement->_next)
		{
			deleteItem(pElement->_next);
		}
	}
}

bool CHashTable::insert(const char * key,void* value)
{
	HashElement * element = new HashElement;
	int key_len = strlen(key);
	//int value_len = strlen(value);
	char* Key = new char[key_len+1];
	//char* Value = new char[value_len+1];
	strcpy(Key,key);
	//strcpy(Value,value);
	element->_key = Key;
	element->_value = value;

	int pos = hash(key);
	HashElement* pElement = &m_pHashTable[pos];

	//if (!pElement->_prvi && !pElement->_next)//first pos with no element
	//{
	//	memcpy(pElement,element,sizeof(element));
	//	delete element;
	//	return true;
	//}

	while(pElement->_next)
		pElement = pElement->_next;

	pElement->_next = element;
	element->_prvi = pElement;

	return true;
}

bool CHashTable::remove(const char * key)
{
	int pos = hash(key);
	HashElement* pElement = &m_pHashTable[pos];
	//if (!pElement->_prvi && !pElement->_next)//first pos with no element
	//	return true;

	while (pElement->_next)
	{
		pElement = pElement->_next;
		if (pElement->_key && strcmp(key,pElement->_key) == 0)
		{
			deleteItem(pElement);

			return true;
		}
	}

	return false;
}

void * CHashTable::getValue(const char* key)
{
	int pos = hash(key);
	HashElement* pElement = &m_pHashTable[pos];

	while (pElement->_next)
	{
		pElement = pElement->_next;
		if (pElement->_key && strcmp(key,pElement->_key) == 0)
		{
			return pElement->_value;
		}
	}

	return 0;
}

bool CHashTable::insert(const WCHAR * key,void* value)
{
	DWORD num = WideCharToMultiByte(CP_OEMCP,NULL,key,-1,0,0,0,0);
	char* _keyansi = new char[num];
	WideCharToMultiByte(CP_OEMCP,NULL,key,-1,_keyansi,num,NULL,false);

	return insert(_keyansi,value);
}
bool CHashTable::remove(const WCHAR * key)
{
	DWORD num = WideCharToMultiByte(CP_OEMCP,NULL,key,-1,0,0,0,0);
	char* _keyansi = new char[num];
	WideCharToMultiByte(CP_OEMCP,NULL,key,-1,_keyansi,num,NULL,false);

	return remove((const char *)_keyansi);
}
void * CHashTable::getValue(const WCHAR* key)
{
	DWORD num = WideCharToMultiByte(CP_OEMCP,NULL,key,-1,0,0,0,0);
	char* _keyansi = new char[num];
	WideCharToMultiByte(CP_OEMCP,NULL,key,-1,_keyansi,num,NULL,false);

	return getValue((const char *)_keyansi);
}